/*
 * Copyright (C) 2016, apexes.net. All rights reserved.
 * 
 *        http://www.apexes.net
 * 
 */
package net.apexes.wsonrpc.core;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 *
 */
public class ServiceRegistry {

    private final ConcurrentMap<String, ServiceReflectHolder<?>> holders;

    private boolean allSimpleName = false;

    ServiceRegistry() {
        holders = new ConcurrentHashMap<>();
    }

    /**
     * 如果未设置服务名称就使用serviceClass的simpleName
     * @return 返回当前实例
     */
    public ServiceRegistry allSimpleName() {
        this.allSimpleName = true;
        return this;
    }

    public <T> Binder<T> bind(Class<T> interfaceClass) {
        return new Binder<>(interfaceClass);
    }

    public <T> Binder<T> simpleName(Class<T> interfaceClass) {
        return new Binder<>(interfaceClass).simpleName();
    }

    public <T> ServiceRegistry register(String name, Class<T> interfaceClass, T instance) {
        if (holders.containsKey(name)) {
            throw new IllegalArgumentException("service already exists");
        }
        holders.put(name, new ServiceReflectHolder<>(interfaceClass, instance));
        return this;
    }

    public ServiceRegistry unregister(String name) {
        holders.remove(name);
        return this;
    }

    ServiceMethodInvoker getInvoker(String serviceMethod) {
        int lastIndex = serviceMethod.lastIndexOf('.');
        if (lastIndex < 0) {
            return null;
        }
        String serviceName = serviceMethod.substring(0, lastIndex);
        String methodName = serviceMethod.substring(lastIndex + 1);
        ServiceReflectHolder<?> holder = holders.get(serviceName);
        if (holder != null) {
            return holder.findInvoker(methodName);
        }
        return null;
    }

    /**
     *
     * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
     *
     */
    public class Binder<T> {

        private final Class<T> interfaceClass;
        private String serviceName;
        private boolean simpleName = false;

        Binder(Class<T> interfaceClass) {
            this.interfaceClass = interfaceClass;
        }

        /**
         * 自定义服务名称
         * @param serviceName 服务名称
         * @return 返回当前实例
         */
        public Binder<T> serviceName(String serviceName) {
            this.serviceName = serviceName;
            this.simpleName = false;
            return this;
        }

        /**
         * 如果未设置服务名称就使用serviceClass的simpleName
         * @return 返回当前实例
         */
        public Binder<T> simpleName() {
            this.serviceName = null;
            this.simpleName = true;
            return this;
        }

        public ServiceRegistry toInstance(T instance) {
            return register(serviceName(interfaceClass), interfaceClass, instance);
        }

        private String serviceName(Class<T> serviceClass) {
            if (serviceName != null) {
                return serviceName;
            } else if (simpleName || allSimpleName) {
                return serviceClass.getSimpleName();
            } else {
                return serviceClass.getName();
            }
        }

    }

}
